﻿using log4net;
using log4net.Repository;
using System;
using System.IO;
using System.Reflection;
using System.Text;

namespace RuoVea.ExLog
{
    /// <summary>
    /// 创建人：starry
    /// 描 述：LogFactory 操作方法
    /// </summary>
    public class LogFactory
    {
        /// <summary>
        /// 
        /// </summary>
        public static void CreaterConfig()
        {
            string fullPath = Path.Combine(Environment.CurrentDirectory, "log4net.config");

            if (!File.Exists(fullPath))
            {
                File.Create(fullPath);
                string config = SetConfig()?.ToString();
                File.AppendAllText(fullPath, config);
            }
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        static ILoggerRepository repository = LogManager.CreateRepository("NETCoreRepository");
        static LogFactory()
        {
            if (repository == null)
                repository = LogManager.CreateRepository("NETCoreRepository");
            //指定配置文件
            log4net.Config.XmlConfigurator.Configure(repository, new FileInfo("log4net.config"));
        }
        /// <summary>
        /// 获取日志操作对象
        /// </summary>
        /// <param name="type">类型</param>
        /// <returns></returns>
        public static Log GetLogger(Type type)
        {
            return new Log(LogManager.GetLogger(type));
        }

        /// <summary>
        /// 获取日志操作对象
        /// </summary>
        /// <param name="str">名字</param>
        /// <returns></returns>
        public static Log GetLogger(string str)
        {
            return new Log(LogManager.GetLogger(repository.Name, str));
        }


        #region Info
        /// <summary>
        /// Info
        /// </summary>
        /// <param name="error"></param>
        public static void Info(string error)
        {
            TextInfo(error);
        }

        static void TextInfo(string error)
        {
            error = error + "\r\n";
            var log = LogFactory.GetLogger("info");
            LogMessage logMessage = new LogMessage();
            log.Info(error);
        }
        #endregion

        #region Debug
        /// <summary>
        /// Debug
        /// </summary>
        /// <param name="error"></param>
        public static void Debug(string error)
        {
            TextDebug(error);
        }

        static void TextDebug(string error)
        {
            error = error + "\r\n";
            var log = LogFactory.GetLogger("debug");
            LogMessage logMessage = new LogMessage();
            log.Debug(error);
        }
        #endregion

        #region Warn
        /// <summary>
        /// Warn
        /// </summary>
        /// <param name="error"></param>
        public static void Warn(string error)
        {
            TextWarn(error);
        }

        static void TextWarn(string error)
        {
            try
            {
                error = error + "\r\n";
                var log = LogFactory.GetLogger("Warn");
                LogMessage logMessage = new LogMessage();
                log.Warn(error);
            }
            catch { }
        }
        #endregion

        #region Error

        /// <summary>
        /// Error
        /// </summary>
        /// <param name="error"></param>
        public static void Error(string error)
        {
            TextError(error);
        }
        /// <summary>
        /// Error
        /// </summary>
        /// <param name="error"></param>
        public static void Error(Exception error)
        {
            TextError(error);
        }
        /// <summary>
        /// Error
        /// </summary>
        /// <param name="title"></param>
        /// <param name="error"></param>
        public static void Error(string title, Exception error)
        {
            TextError(error, title);
        }
        static void TextError(string error)
        {
            error = error + "\r\n";
            var log = LogFactory.GetLogger("error");
            LogMessage logMessage = new LogMessage();
            log.Error(error);
        }
        /// <summary>
        /// Error
        /// </summary>
        /// <param name="logMessage"></param>
        public static void Error(LogMessage logMessage)
        {

            var log = LogFactory.GetLogger("error");
            string strMessage = new LogFormat().ExceptionFormat(logMessage);
            log.Error(strMessage);

        }

        static void TextError(Exception error, string title = null)
        {
            var log = LogFactory.GetLogger("error");
            LogMessage logMessage = new LogMessage();
            logMessage.OperationTime = DateTime.Now;
            if (error.InnerException == null)
            {
                logMessage.ExceptionInfo = error.Message;
            }
            else
            {
                logMessage.ExceptionInfo = error.InnerException.Message;
            }

            if (!string.IsNullOrWhiteSpace(title))
                logMessage.ExceptionInfo = title + " : " + logMessage.ExceptionInfo;

            MethodBase methodBase = System.Reflection.MethodBase.GetCurrentMethod();

            logMessage.Class = methodBase.DeclaringType.FullName;
            logMessage.ExceptionSource = error.Source;
            logMessage.ExceptionRemark = error.StackTrace;
            string strMessage = new LogFormat().ExceptionFormat(logMessage);
            log.Error(strMessage);
        }
        #endregion

        #region SetConfig
        private static StringBuilder SetConfig()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
            sb.Append("<log4net>");
            sb.Append("  <!--根配置-->");
            sb.Append("  <root>");
            sb.Append("    <!--日志级别:可选值: ERROR > WARN > INFO > DEBUG -->");
            sb.Append("    <level value=\"ERROR\"/>");
            sb.Append("    <level value=\"WARN\"/>");
            sb.Append("    <level value=\"INFO\"/>");
            sb.Append("    <level value=\"DEBUG\"/>");
            sb.Append("    <appender-ref ref=\"ErrorLog\" />");
            sb.Append("    <appender-ref ref=\"WarnLog\" />");
            sb.Append("    <appender-ref ref=\"InfoLog\" />");
            sb.Append("    <appender-ref ref=\"DebugLog\" />");
            sb.Append("  </root>");
            sb.Append("  <!-- 错误 Error.log-->");
            sb.Append("  <appender name=\"ErrorLog\" type=\"log4net.Appender.RollingFileAppender\">");
            sb.Append("	  <!--记录日志写入文件时，不锁定文本文件，防止多线程时不能写Log,官方说线程非安全-->");
            sb.Append("	  <lockingModel type=\"log4net.Appender.FileAppender+MinimalLock\" />");
            sb.Append("    <!--目录路径，可以是相对路径或绝对路径-->");
            sb.Append("    <param name=\"File\" value=\"log/ \"/>");
            sb.Append("    <!--文件名，按日期生成文件夹-->");
            sb.Append("    <param name=\"DatePattern\" value=\"/yyyy-MM-dd/&quot;Error.log&quot; \"/>");
            sb.Append("    <!--追加到文件-->");
            sb.Append("    <appendToFile value=\"true\"/>");
            sb.Append("    <!--创建日志文件的方式，可选值：Date[日期],文件大小[Size],混合[Composite]-->");
            sb.Append("    <rollingStyle value=\"Composite\"/>");
            sb.Append("    <!--写到一个文件-->");
            sb.Append("    <staticLogFileName value=\"false\"/>");
            sb.Append("    <!--单个文件大小。单位:KB|MB|GB-->");
            sb.Append("    <maximumFileSize value=\"200MB\"/>");
            sb.Append("    <!--最多保留的文件数，设为\"-1\"则不限-->");
            sb.Append("    <maxSizeRollBackups value=\"-1\"/>");
            sb.Append("    <!--日志格式-->");
            sb.Append("    <layout type=\"log4net.Layout.PatternLayout\">");
            sb.Append("      <conversionPattern value=\"%message\"/>");
            sb.Append("    </layout>");
            sb.Append("    <filter type=\"log4net.Filter.LevelRangeFilter\">");
            sb.Append("      <param name=\"LevelMin\" value=\"ERROR\" />");
            sb.Append("      <param name=\"LevelMax\" value=\"ERROR\" />");
            sb.Append("    </filter>");
            sb.Append("  </appender>");
            sb.Append("");
            sb.Append("  <!-- 警告 Warn.log-->");
            sb.Append("  <appender name=\"WarnLog\" type=\"log4net.Appender.RollingFileAppender\">");
            sb.Append("	  <!--记录日志写入文件时，不锁定文本文件，防止多线程时不能写Log,官方说线程非安全-->");
            sb.Append("	  <lockingModel type=\"log4net.Appender.FileAppender+MinimalLock\" />");
            sb.Append("    <!--目录路径，可以是相对路径或绝对路径-->");
            sb.Append("    <param name=\"File\" value=\"log/ \"/>");
            sb.Append("    <!--文件名，按日期生成文件夹-->");
            sb.Append("    <param name=\"DatePattern\" value=\"/yyyy-MM-dd/&quot;Warn.log&quot; \"/>");
            sb.Append("    <!--追加到文件-->");
            sb.Append("    <appendToFile value=\"true\"/>");
            sb.Append("    <!--创建日志文件的方式，可选值：Date[日期],文件大小[Size],混合[Composite]-->");
            sb.Append("    <rollingStyle value=\"Composite\"/>");
            sb.Append("    <!--写到一个文件-->");
            sb.Append("    <staticLogFileName value=\"false\"/>");
            sb.Append("    <!--单个文件大小。单位:KB|MB|GB-->");
            sb.Append("    <maximumFileSize value=\"200MB\"/>");
            sb.Append("    <!--最多保留的文件数，设为\"-1\"则不限-->");
            sb.Append("    <maxSizeRollBackups value=\"-1\"/>");
            sb.Append("    <!--日志格式-->");
            sb.Append("    <layout type=\"log4net.Layout.PatternLayout\">");
            sb.Append("      <conversionPattern value=\"%message\"/>");
            sb.Append("    </layout>");
            sb.Append("    <filter type=\"log4net.Filter.LevelRangeFilter\">");
            sb.Append("      <param name=\"LevelMin\" value=\"WARN\" />");
            sb.Append("      <param name=\"LevelMax\" value=\"WARN\" />");
            sb.Append("    </filter>");
            sb.Append("  </appender>");
            sb.Append("");
            sb.Append("  <!-- 信息 Info.log-->");
            sb.Append("  <appender name=\"InfoLog\" type=\"log4net.Appender.RollingFileAppender\">");
            sb.Append("	  <!--记录日志写入文件时，不锁定文本文件，防止多线程时不能写Log,官方说线程非安全-->");
            sb.Append("	  <lockingModel type=\"log4net.Appender.FileAppender+MinimalLock\" />");
            sb.Append("    <!--目录路径，可以是相对路径或绝对路径-->");
            sb.Append("    <param name=\"File\" value=\"log/ \"/>");
            sb.Append("    <!--文件名，按日期生成文件夹-->");
            sb.Append("    <param name=\"DatePattern\" value=\"/yyyy-MM-dd/&quot;Info.log&quot; \"/>");
            sb.Append("    <!--追加到文件-->");
            sb.Append("    <appendToFile value=\"true\"/>");
            sb.Append("    <!--创建日志文件的方式，可选值：Date[日期],文件大小[Size],混合[Composite]-->");
            sb.Append("    <rollingStyle value=\"Composite\"/>");
            sb.Append("    <!--写到一个文件-->");
            sb.Append("    <staticLogFileName value=\"false\"/>");
            sb.Append("    <!--单个文件大小。单位:KB|MB|GB-->");
            sb.Append("    <maximumFileSize value=\"200MB\"/>");
            sb.Append("    <!--最多保留的文件数，设为\"-1\"则不限-->");
            sb.Append("    <maxSizeRollBackups value=\"-1\"/>");
            sb.Append("    <!--日志格式-->");
            sb.Append("    <layout type=\"log4net.Layout.PatternLayout\">");
            sb.Append("      <conversionPattern value=\"%message\"/>");
            sb.Append("    </layout>");
            sb.Append("    <filter type=\"log4net.Filter.LevelRangeFilter\">");
            sb.Append("      <param name=\"LevelMin\" value=\"INFO\" />");
            sb.Append("      <param name=\"LevelMax\" value=\"INFO\" />");
            sb.Append("    </filter>");
            sb.Append("  </appender>");
            sb.Append("");
            sb.Append("  <!-- 调试 Debug.log-->");
            sb.Append("  <appender name=\"DebugLog\" type=\"log4net.Appender.RollingFileAppender\">");
            sb.Append("	  <!--记录日志写入文件时，不锁定文本文件，防止多线程时不能写Log,官方说线程非安全-->");
            sb.Append("	  <lockingModel type=\"log4net.Appender.FileAppender+MinimalLock\" />");
            sb.Append("    <!--目录路径，可以是相对路径或绝对路径-->");
            sb.Append("    <param name=\"File\" value=\"log/ \"/>");
            sb.Append("    <!--文件名，按日期生成文件夹-->");
            sb.Append("    <param name=\"DatePattern\" value=\"/yyyy-MM-dd/&quot;Debug.log&quot; \"/>");
            sb.Append("    <!--追加到文件-->");
            sb.Append("    <appendToFile value=\"true\"/>");
            sb.Append("    <!--创建日志文件的方式，可选值：Date[日期],文件大小[Size],混合[Composite]-->");
            sb.Append("    <rollingStyle value=\"Composite\"/>");
            sb.Append("    <!--写到一个文件-->");
            sb.Append("    <staticLogFileName value=\"false\"/>");
            sb.Append("    <!--单个文件大小。单位:KB|MB|GB-->");
            sb.Append("    <maximumFileSize value=\"200MB\" /> ");
            sb.Append("    <!--最多保留的文件数，设为\"-1\"则不限-->");
            sb.Append("    <maxSizeRollBackups value=\"-1\"/>");
            sb.Append("    <!--日志格式-->");
            sb.Append("    <layout type=\"log4net.Layout.PatternLayout\">");
            sb.Append("      <conversionPattern value=\"%message\"/>");
            sb.Append("    </layout>");
            sb.Append("    <filter type=\"log4net.Filter.LevelRangeFilter\">");
            sb.Append("      <param name=\"LevelMin\" value=\"DEBUG\" />");
            sb.Append("      <param name=\"LevelMax\" value=\"DEBUG\" />");
            sb.Append("    </filter>");
            sb.Append("  </appender>");
            sb.Append("  ");
            sb.Append(" </log4net>");

            return sb;
        }
        #endregion
    }
}
